Android volley 使用OkHttp3.0

本文仅介绍如何使用OKHttp3.0实现HttpStack,从而接管volley的网络请求。

##前言:
volley —- Google出品的android平台轻量级网络库
    优点:扩展性强,请求队列管理
     基本介绍:http://blog.csdn.net/t12x3456/article/details/9221611/
     github镜像: https://github.com/mcxiaoke/android-volley

okhttp—-Square出品的java网络库,android4.4以后已作为默认的HTTP连接实现
     优点:支持SPDY,连接池,传输效率的各种优化
     源码:https://github.com/square/okhttp
     官方wiki:https://github.com/square/okhttp/wiki

##正文:
OkHttp 3.x相对于2.x,在api以及使用规范上有一些调整,所以在实现HttpStack的时候要做相应的更改,基本用法不变。
参考来源:http://blog.csdn.net/lonewolf521125/article/details/47256475

下面直接上代码,红色部分关注一下即可。
复制代码 1 package com.xxx.xxx; 2
3 import com.android.volley.AuthFailureError; 4 import com.android.volley.Request; 5 import com.android.volley.toolbox.HttpStack; 6
7 import org.apache.http.HttpEntity; 8 import org.apache.http.HttpResponse; 9 import org.apache.http.ProtocolVersion; 10 import org.apache.http.StatusLine; 11 import org.apache.http.entity.BasicHttpEntity; 12 import org.apache.http.message.BasicHeader; 13 import org.apache.http.message.BasicHttpResponse; 14 import org.apache.http.message.BasicStatusLine; 15
16 import java.io.IOException; 17 import java.util.Map; 18 import java.util.concurrent.TimeUnit; 19
20 import okhttp3.Call; 21 import okhttp3.Headers; 22 import okhttp3.MediaType; 23 import okhttp3.OkHttpClient; 24 import okhttp3.Protocol; 25 import okhttp3.RequestBody; 26 import okhttp3.Response; 27 import okhttp3.ResponseBody; 28
29 /
30 The MIT License (MIT) 31

32 Copyright (c) 2015 Circle Internet Financial 33

34 Permission is hereby granted, free of charge, to any person obtaining a copy 35 of this software and associated documentation files (the “Software”), to deal 36 in the Software without restriction, including without limitation the rights 37 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 38 copies of the Software, and to permit persons to whom the Software is 39 furnished to do so, subject to the following conditions: 40

41

The above copyright notice and this permission notice shall be included in 42 all copies or substantial portions of the Software. 43

44 THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 45 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 46 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 47 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 48 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 49 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 50 THE SOFTWARE. 51 /
52
53 /


54 OkHttp backed {@link com.android.volley.toolbox.HttpStack HttpStack} that 55 does not use okhttp-urlconnection 56 */
57 public class OkHttpStack implements HttpStack { 58
59 private final OkHttpClient mClient; 60
61 public OkHttpStack(OkHttpClient client) { 62 this.mClient = client; 63 } 64
65 @Override 66 public HttpResponse performRequest(Request<?> request, 67 Map additionalHeaders) throws IOException, AuthFailureError { 68
69 int timeoutMs = request.getTimeoutMs(); 70 // okhttp 3.0以后的版本构建OkHttpClient使用Builder
71 OkHttpClient.Builder builder = mClient.newBuilder(); 72 builder.connectTimeout(timeoutMs, TimeUnit.MILLISECONDS) 73 .readTimeout(timeoutMs, TimeUnit.MILLISECONDS) 74 .writeTimeout(timeoutMs, TimeUnit.MILLISECONDS); 75 OkHttpClient client = builder.build(); 76
77 okhttp3.Request.Builder okHttpRequestBuilder = new okhttp3.Request.Builder(); 78 okHttpRequestBuilder.url(request.getUrl()); 79
80 Map headers = request.getHeaders(); 81 for (final String name : headers.keySet()) { 82 okHttpRequestBuilder.addHeader(name, headers.get(name)); 83 } 84 for (final String name : additionalHeaders.keySet()) { 85 // 这里用header方法,如果有重复的name,会覆盖,否则某些请求会被判定为非法
86 okHttpRequestBuilder.header(name, additionalHeaders.get(name)); 87 } 88
89 setConnectionParametersForRequest(okHttpRequestBuilder, request); 90
91 okhttp3.Request okHttpRequest = okHttpRequestBuilder.build(); 92 Call okHttpCall = client.newCall(okHttpRequest); 93 Response okHttpResponse = okHttpCall.execute(); 94
95 StatusLine responseStatus = new BasicStatusLine( 96 parseProtocol(okHttpResponse.protocol()), okHttpResponse.code(), 97 okHttpResponse.message()); 98 BasicHttpResponse response = new BasicHttpResponse(responseStatus); 99 response.setEntity(entityFromOkHttpResponse(okHttpResponse));100
101 Headers responseHeaders = okHttpResponse.headers();102 for (int i = 0, len = responseHeaders.size(); i < len; i++) {103 final String name = responseHeaders.name(i), value = responseHeaders.value(i);104 if (name != null) {105 response.addHeader(new BasicHeader(name, value));106 }107 }108
109 return response;110 }111
112 private static HttpEntity entityFromOkHttpResponse(Response r) throws IOException {113 BasicHttpEntity entity = new BasicHttpEntity();114 ResponseBody body = r.body();115
116 entity.setContent(body.byteStream());117 entity.setContentLength(body.contentLength());118 entity.setContentEncoding(r.header(“Content-Encoding”));119
120 if (body.contentType() != null) {121 entity.setContentType(body.contentType().type());122 }123 return entity;124 }125
126 @SuppressWarnings(“deprecation”)127 private static void setConnectionParametersForRequest(128 okhttp3.Request.Builder builder, Request<?> request) throws IOException,129 AuthFailureError {130 switch (request.getMethod()) {131 case Request.Method.DEPRECATED_GET_OR_POST:132 // Ensure backwards compatibility. Volley assumes a request with133 // a null body is a GET.
134 byte[] postBody = request.getPostBody();135 if (postBody != null) {136 builder.post(RequestBody.create(137 MediaType.parse(request.getPostBodyContentType()), postBody));138 }139 break;140 case Request.Method.GET:141 builder.get();142 break;143 case Request.Method.DELETE:144 builder.delete();145 break;146 case Request.Method.POST:147 builder.post(createRequestBody(request));148 break;149 case Request.Method.PUT:150 builder.put(createRequestBody(request));151 break;152 case Request.Method.HEAD:153 builder.head();154 break;155 case Request.Method.OPTIONS:156 builder.method(“OPTIONS”, null);157 break;158 case Request.Method.TRACE:159 builder.method(“TRACE”, null);160 break;161 case Request.Method.PATCH:162 builder.patch(createRequestBody(request));163 break;164 default:165 throw new IllegalStateException(“Unknown method type.”);166 }167 }168
169 private static ProtocolVersion parseProtocol(final Protocol p) {170 switch (p) {171 case HTTP_1_0:172 return new ProtocolVersion(“HTTP”, 1, 0);173 case HTTP_1_1:174 return new ProtocolVersion(“HTTP”, 1, 1);175 case SPDY_3:176 return new ProtocolVersion(“SPDY”, 3, 1);177 case HTTP_2:178 return new ProtocolVersion(“HTTP”, 2, 0);179 }180
181 throw new IllegalAccessError(“Unkwown protocol”);182 }183
184 private static RequestBody createRequestBody(Request r) throws AuthFailureError {185 byte[] body = r.getBody();186 if (body == null) {187 // OkHttp内部默认的的判断逻辑是POST 不能为空,这里做了规避
188 if (r.getMethod() == Request.Method.POST) {189 body = “”.getBytes();190 }191 else {192 return null;193 }194 }195
196 return RequestBody.create(MediaType.parse(r.getBodyContentType()), body);197 }198 }
复制代码 在volley的调用:
1 OkHttpClient okClient = new OkHttpClient.Builder().build();2
3 RequestQueue queue = Volley.newRequestQueue(context, new OkHttpStack(okClient));

Contents
,